package com.tju.resource.server.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tju.resource.common.ServiceException;
import com.tju.resource.mapper.*;
import com.tju.resource.model.*;
import com.tju.resource.server.SysParamsService;
import com.tju.resource.server.TbOrderService;
import com.tju.resource.server.TbShipmentService;
import com.tju.resource.tool.result.Result;
import com.tju.resource.tool.result.ResultEnum;
import com.tju.resource.tool.result.ResultUtil;
import com.tju.resource.tool.tool.ChineseExceptionUtils;
import com.tju.resource.tool.tool.ClientParameters;
import com.tju.resource.tool.tool.EmptyUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * 出货业务
 */
@Service
public class TbShipmentServiceImpl extends ServiceImpl<TbShipmentMapper, TbShipment>
        implements TbShipmentService {
    private static int noIndex = 0;
    @Autowired
    private TbShipmentMapper tbShipmentMapper;
    @Autowired
    private TbShipMatlMapper tbShipMatlMapper;
    @Autowired
    private ChineseExceptionUtils zh_CH;
    @Autowired
    private TbMaterialMapper tbMaterialMapper;
    @Autowired
    private TbOrdMatlMapper tbOrdMatlMapper;
    @Autowired
    private TbOrderService tbOrderService;
    @Autowired
    private TbOrderMapper tbOrderMapper;
    @Autowired
    private TbShipmentConsumablesMapper tbShipmentConsumablesMapper;
    @Autowired
    private SysParamsService paramsServiceService;
    @Autowired
    private TbSendMatlMapper tbSendMatlMapper;

    /**
     * 查询出货
     *
     * @param parameter
     * @return
     */
    @Override
    public Result<Object> selectShipment(ClientParameters parameter) {
        try {
            Integer pageNum = parameter.getPage();
            Integer limit = parameter.getLimit();
            if (EmptyUtils.isNotEmpty(pageNum) && EmptyUtils.isNotEmpty(limit)) {
                Page<TbShipment> page = new Page<>(pageNum, limit);//分页
                IPage<TbShipment> iPage = tbShipmentMapper.selectShipment(page, parameter);//查询
                List<TbShipment> records = iPage.getRecords(); //接收集合
                for (TbShipment shipment : records) {//循环关联的物料
                    //物料
                    List<TbShipMatl> tbShipMatls = tbShipmentMapper.shipMatlById(shipment.getOrderId(), shipment.getId());
                    //耗材
                    List<TbShipmentConsumables> shipmentConsumables = tbShipmentMapper.selectShipmentConsumablesList(shipment.getId());
                    shipment.setTbShipmentConsumablesList(shipmentConsumables);
                    long shipGtyTotal = 0L;//总出货数
                    long boxQtyTotal = 0L;//总出箱数
                    long lastBoxTotal = 0L;//尾箱总数
                    for (TbShipMatl shipMatl : tbShipMatls) {
                        shipGtyTotal += shipMatl.getShipQty() == null ? 0 : shipMatl.getShipQty(); //算出总出货数
                        boxQtyTotal += shipMatl.getBoxQty() == null ? 0 : shipMatl.getBoxQty(); //算出总出箱数
                        lastBoxTotal += shipMatl.getLastBox() == null ? 0 : shipMatl.getLastBox();//尾箱总数
                    }
                    shipment.setLastBoxTotal(lastBoxTotal);//总出货数
                    shipment.setShipGtyTotal(shipGtyTotal);//总出箱数
                    shipment.setBoxQtyTotal(boxQtyTotal);//尾箱总数
                }
                return ResultUtil.success(ResultEnum.SUCCESS, records, records.size());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ResultUtil.error(ResultEnum.UNKONW_ERROR, zh_CH.MissingParameters);
    }

    /**
     * 新增出货
     *
     * @param shipment
     * @return
     */
    @Override
    @Transactional
    public Result<Object> insertShipment(TbShipment shipment) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyMMdd");  //转换
        noIndex = noIndex + 1;  //自增
        shipment.setSn(formatter.format(new Date()) + noIndex); //自动生成吧sn
        if (tbShipmentMapper.insert(shipment) > 0) {
            insertShipMatl(shipment); //添加物料
            return ResultUtil.success(ResultEnum.SUCCESS, zh_CH.AddedSuccessfully);
        }
        return ResultUtil.error(ResultEnum.UNKONW_ERROR, zh_CH.AddFailed);
    }

    /**
     * 修改出货
     *
     * @param shipment
     * @return
     */
    @Override
    @Transactional
    public Result<Object> updateShipment(TbShipment shipment) {
        if (EmptyUtils.isNotEmpty(shipment.getId())) {
            if (tbShipmentMapper.updateById(shipment) > 0) {
                deleteShipMatlById(shipment.getId());
                insertShipMatl(shipment); //添加物料
                return ResultUtil.success(ResultEnum.SUCCESS, zh_CH.SuccessfullyModified);
            }
        }
        return ResultUtil.error(ResultEnum.UNKONW_ERROR, zh_CH.FailToEdit);
    }

    /**
     * 删除出货
     *
     * @param shipment
     * @return
     */
    @Override
    @Transactional
    public Result<Object> deleteShipment(TbShipment shipment) {
        if (EmptyUtils.isNotEmpty(shipment.getId())) {
            deleteShipMatlById(shipment.getId());
            deleteTbShipmentConsumablesById(shipment.getId());
            if (tbShipmentMapper.deleteById(shipment.getId()) > 0) {
                return ResultUtil.success(ResultEnum.SUCCESS, zh_CH.SuccessfullyDeleted);
            }
        }
        return ResultUtil.error(ResultEnum.UNKONW_ERROR, zh_CH.FailedToDelete);
    }

    /**
     * 审核出货
     *
     * @param shipment
     * @return
     */
    @Override
    @Transactional
    public Result<Object> approveShipment(TbShipment shipment) {
        if (EmptyUtils.isNotEmpty(shipment.getId())) {
            TbShipment shipmentTwo = tbShipmentMapper.selectById(shipment.getId()); //根据id查询出货信息
            Long orderId = shipmentTwo.getOrderId(); //订单id
            if (EmptyUtils.isEmpty(orderId)) throw new ServiceException("订单Id不能为空");
            QueryWrapper<TbShipMatl> qw = new QueryWrapper<>();
            qw.eq("shipment_id", shipment.getId());
            List<TbShipMatl> tbShipMatls = tbShipMatlMapper.selectList(qw);
            TbOrder tbOrder = tbOrderMapper.selectById(orderId);
            TbOrdMatl tbOrdMatl;
            TbMaterial tbMaterial;
            Long orderPcsTotal = 0L;  //完成数量
            for (TbShipMatl tbShipMatl : tbShipMatls) {
                Long matlId = tbShipMatl.getMatlId(); //物料id
                tbOrdMatl = tbOrdMatlMapper.selectTbOrdMatlByIdAndOrderId(orderId, matlId); //查询物料跟订单关联表
                //订单完成数量  订单完成数加上出货数量
                long finishQuantity = tbOrdMatl.getFinishQuantity() == null ? tbShipMatl.getShipQty() : tbOrdMatl.getFinishQuantity() + tbShipMatl.getShipQty();
                tbOrdMatl.setFinishQuantity(finishQuantity);
                //订单未完成数量  订单总数量减去订单完成数量
                long unFinishQuantity = tbOrdMatl.getOrderPcs() - finishQuantity;
                tbOrdMatl.setUnFinishQuantity(unFinishQuantity < 0 ? 0 : unFinishQuantity);//未完成
                tbOrdMatlMapper.updateById(tbOrdMatl); //修改订单跟物料关联表的完成数量跟未完成数量
                tbMaterial = tbMaterialMapper.selectById(matlId); //查询物料信息
                tbMaterial.setFpPcs(tbMaterial.getFpPcs() - tbShipMatl.getShipQty()); //成品数量-出货数量
                tbMaterialMapper.updateById(tbMaterial); //修改
                tbOrderService.updateOrdMatl(tbOrder.getOrderNumber(), tbMaterial.getMatlNumber());  //修改缺少数量跟缺少重量s
                if (tbOrdMatl.getOrderPcs().equals(finishQuantity))  //订单数完成就加
                {
                    //查询模具寿命
                    TbMaterial matl = tbMaterialMapper.selectByMatilId(tbOrdMatl.getMatiId());
                    //修改剩余寿命和缓存寿命
                    tbOrderService.updateSharper(matl.getSid(), matl.getResidualLife() + tbOrdMatl.getOrderPcs(), (matl.getWithholdingLife() - tbOrdMatl.getOrderPcs()));
                    orderPcsTotal += tbOrdMatl.getOrderPcs();
                }


            }
            if (orderPcsTotal.equals(tbOrder.getPlanNumber())) {//判断数量完成
                tbOrder.setOrderState(1L);
                tbOrderMapper.updateById(tbOrder);//修改订单为完成
            }
            shipment.setApproveStatus(1);
            shipment.setApproveTime(new Date());
            if (tbShipmentMapper.updateById(shipment) > 0) {
                return ResultUtil.success(ResultEnum.SUCCESS, "审核通过！");
            }
        }
        return ResultUtil.error(ResultEnum.UNKONW_ERROR, "审核失败！");
    }

    @Override
    @Transactional
    public Result<Object> shipConsumables(TbShipment shipment) {
        if (EmptyUtils.isNotEmpty(shipment.getId())) { //出货id不能为空
            deleteTbShipmentConsumablesById(shipment.getId());
            List<TbShipmentConsumables> tbShipmentConsumablesList = shipment.getTbShipmentConsumablesList();//耗材集合
            if (EmptyUtils.isNotEmpty(tbShipmentConsumablesList)) {  //耗材不能为空
                for (TbShipmentConsumables shipmentConsumables : tbShipmentConsumablesList) { //循环添加
                    if (EmptyUtils.isEmpty(shipmentConsumables.getShipmentMaterialNumber()) || shipmentConsumables.getShipmentMaterialNumber() == 0)
                        return ResultUtil.error(ResultEnum.UNKONW_ERROR, "出货耗材不能为空跟不能为0!");
                    shipmentConsumables.setConsumablesId(shipmentConsumables.getId());//耗材id
                    shipmentConsumables.setShipmentId(shipment.getId());//出货id
                    shipmentConsumables.setId(null);
                    tbShipmentConsumablesMapper.insert(shipmentConsumables);//添加耗材
                }
            } else {
                return ResultUtil.error(ResultEnum.UNKONW_ERROR, "耗材不能为空!");
            }
            return ResultUtil.success(ResultEnum.SUCCESS, "添加耗材成功");
        } else {
            return ResultUtil.error(ResultEnum.UNKONW_ERROR, "出货id不存在");
        }

    }

    @Override
    /**
     * 审核耗材
     */
    @Transactional
    public Result<Object> approveShipConsumables(TbShipment shipment) {
        if (EmptyUtils.isNotEmpty(shipment.getId())) {

            String paramsValue = paramsServiceService.get("MATL_SRC_OS").getRemark();//来源
            for (TbShipmentConsumables shipmentConsumables : shipment.getTbShipmentConsumablesList()) {
                TbSendMatl tbSendMatl = new TbSendMatl();//发料对象
                tbSendMatl.setConsumablesId(shipmentConsumables.getId()); //耗材
                tbSendMatl.setCreateBy(shipment.getCreateBy()); //创建人
                tbSendMatl.setMatlSrc(paramsValue);//来源
                tbSendMatl.setShipmentId(shipment.getId()); //出货id
                tbSendMatlMapper.insert(tbSendMatl);//添加发料
                return ResultUtil.success(ResultEnum.SUCCESS, "审核成功!");
            }
        } else return ResultUtil.error(ResultEnum.UNKONW_ERROR, "不存在出货信息!");
        return ResultUtil.error(ResultEnum.UNKONW_ERROR, "审核失败!");
    }

    /**
     * 删除之前关联物料的
     *
     * @param id
     */
    private void deleteShipMatlById(Long id) {
        QueryWrapper<TbShipMatl> qw = new QueryWrapper<>();
        qw.eq("shipment_id", id);
        List<TbShipMatl> tbShipMatls = tbShipMatlMapper.selectList(qw);
        for (TbShipMatl tbShipMatl : tbShipMatls) {
            tbShipMatlMapper.deleteById(tbShipMatl.getId());
        }
    }

    /**
     * 删除之前关联耗材的
     *
     * @param id
     */
    private void deleteTbShipmentConsumablesById(Long id) {
        QueryWrapper<TbShipmentConsumables> qw = new QueryWrapper<>();
        qw.eq("shipment_id", id);
        List<TbShipmentConsumables> shipmentConsumablesList = tbShipmentConsumablesMapper.selectList(qw);
        for (TbShipmentConsumables shipmentConsumables : shipmentConsumablesList) {
            tbShipmentConsumablesMapper.deleteById(shipmentConsumables.getId());
        }
    }

    /**
     * 添加出货关联的物料
     *
     * @param shipment
     */
    private void insertShipMatl(TbShipment shipment) {
        if (EmptyUtils.isNotEmpty(shipment.getShipMatlList())) {
            List<TbShipMatl> shipMatlList = shipment.getShipMatlList();
            TbMaterial material;
            for (TbShipMatl tbShipMatl : shipMatlList) {
                if (EmptyUtils.isEmpty(tbShipMatl.getShipQty()) || EmptyUtils.isEmpty(tbShipMatl.getPackQty())) {
                    throw new ServiceException("出货数量跟装箱数量不能为空!");
                }
                tbShipMatl.setShipmentId(shipment.getId());
                material = tbMaterialMapper.selectById(tbShipMatl.getMatlId());
                long fpPcs = EmptyUtils.isEmpty(material.getFpPcs()) ? 0 : material.getFpPcs();
                if (fpPcs < tbShipMatl.getShipQty()) {
                    throw new ServiceException("出货数量不能大于库存数量!");
                }
                tbShipMatlMapper.insert(tbShipMatl);
            }
        } else {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            throw new ServiceException("未选择物料!");
        }
    }
}




